home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / mail / listserv / utils / better-redux.pl.Z / better-redux.pl
Encoding:
Internet Message Format  |  1993-10-25  |  9.8 KB

  1. From bahainvs!johnw@cs.UMD.EDU Sun Oct 24 14:20:57 1993
  2. Return-Path: <bahainvs!johnw@cs.UMD.EDU>
  3. Received: from mimsy.cs.umd.edu by cs-mail.bu.edu (5.61+++/Spike-2.1)
  4.     id AA23292; Sun, 24 Oct 93 14:20:53 -0400
  5. Received: from bahainvs.UUCP 
  6.     by mimsy.cs.UMD.EDU (5.64/UMIACS-0.9/04-05-88)
  7.     id AA10406; Sun, 24 Oct 93 14:20:52 -0400
  8. Received: by bahainvs.org 
  9.     id m0or9tg-000KgjC; Sun, 24 Oct 93 14:10 EDT
  10. Message-Id: <m0or9tg-000KgjC@bahainvs.org>
  11. From: johnw@bahainvs.org (John Wiegley)
  12. Subject: A new version of redux, and a command-line utility for ListProc 6.0
  13. To: tasos@cs.bu.edu (Anastasios Kotsikonas)
  14. Date: Sun, 24 Oct 1993 14:10:31 EDT
  15. In-Reply-To: <9310211528.AA16740@cs.bu.edu> from "Anastasios Kotsikonas" at Oct 21, 93 11:28:49 am
  16. Reply-To: johnw@bahainvs.org
  17. X-Mailer: ELM [version 2.4 PL22]
  18. Content-Type: text
  19. Content-Length: 9196      
  20. Status: RO
  21.  
  22. Tasos,
  23.  
  24. First, here's a new version of "redux", rewritten in perl, along with a
  25. program called "mgzip", which I use to archive mailboxes rather than
  26. just "gzip".  That is, of course, unless your users really WANT all
  27. those e-mail headers.  I figure that they can have them if they're
  28. non-digested, but if they aren't, they can live with straight text and
  29. very few headers.
  30.  
  31. (This script is about 4 times slower, but much more complete than
  32.  the shell version.  That is, it ONLY finds matches inside of
  33.  headers.)
  34.  
  35. ---[ file: redux ]---
  36. #!/usr/bin/perl
  37.  
  38. open(FILE, $file = shift(@ARGV));
  39. open(TMP, "> /tmp/redux.$$");
  40. select TMP;
  41.  
  42. while( <FILE> )
  43. {
  44.     study;
  45.  
  46.     $inheader = 1            if( ! $inheader && /^From / );
  47.     print, next            if( ! $inheader );
  48.     $inheader = 0, print, next    if(   $inheader && /^\n/ );
  49.  
  50.     /^Apparently-/            && next;
  51.     /^Approved-By:/            && next;
  52.     /^Comment:/            && next;
  53.     /^Content-/            && next;
  54.     /^Date:/            && next;
  55.     /^Delivered-By-The-Graces-Of:/    && next;
  56.     /^Errors-To:/            && next;
  57.     /^In-Reply-To:/            && next;
  58.     /^M[Ii][Mm][Ee]-/        && next;
  59.     /^Mail-System-Version:/        && next;
  60.     /^Mailer:/            && next;
  61.     /^Message-[Ii]d:/        && next;
  62.     /^Newsgroups:/            && next;
  63.     /^Organization:/        && next;
  64.     /^Originator:/            && next;
  65.     /^Posted-Date:/            && next;
  66.     /^Precedence:/            && next;
  67.     /^Received/            && next;
  68.     /^References:/            && next;
  69.     /^Resent-/            && next;
  70.     /^Return-Path:/            && next;
  71.     /^Return-Receipt-To:/        && next;
  72.     /^Sender:/            && next;
  73.     /^Status:/            && next;
  74.     /^Version:/            && next;
  75.     /^X-/                && next;
  76.     /^X400-/            && next;
  77.     /^\s+/                && next;
  78.  
  79.     print;
  80. }
  81.  
  82. close(FILE);
  83. close(TMP);
  84.  
  85. exec("mv /tmp/redux.$$ $file");
  86.  
  87. ---EOF---
  88. ---[ file: mgzip ]---
  89. #!/usr/bin/perl
  90.  
  91. $flag = shift(@ARGV);
  92.  
  93. foreach $file ( @ARGV )
  94. {
  95.     if( $file !~ /\.gz$/ )
  96.     {
  97.         system("redux $file");
  98.         system("gzip $flag $file");
  99.     }
  100. }
  101. ---EOF---
  102.  
  103. Also, here's a command-line interface for ListProcessor.  I
  104. prefer this to the e-mail interface when I'm on my home computer.
  105.  
  106. ---[ file: prc ]---
  107. #!/usr/bin/perl
  108.  
  109. $listproc    = "/usr/listserv";    # SET TO LISTPROCESSOR HOMEDIR DIRECTORY
  110.  
  111. #
  112. # Filename:    prc    - ListProcessor Control Program
  113. #
  114. # Purpose:    to facilitate command-line manipulation of
  115. #        mailing list user accounts.
  116. #
  117. # Notes:    to apply any command to a file containing
  118. #        multiple addresses/lists, use the features
  119. #        of your shell.  Such functionality is not
  120. #        necessary to 'prc'.
  121. #
  122.  
  123. if( ! @ARGV
  124.     || $ARGV[0] =~ /^-h/
  125.     || $ARGV[1] =~ /^-h/ )
  126. {
  127.     print <<"EOH";        # End of Help
  128. usage: $0 option [list_alias] [address [full_name]]
  129.  
  130.     -a   Add a person to a list
  131.     -d   Delete a person from a list
  132.     -t   Tempdown an address
  133.     -b   Put a user on the "digest" program
  134.     -l   List all addresses that have been tempdown'd
  135.     -i   Reinstate a tempdown'd address
  136.     -r   Reject a person (make them unauthorized)
  137.     -p   Request further information from a person
  138.     -f   Find a subscriber on any list
  139.     -h   This help message
  140.  
  141. EOH
  142.     exit 0;
  143. }
  144.  
  145. if( @ARGV == 1 && $ARGV[0] =~ /^-a/ )
  146. {
  147.     warn "This option requires a list_alias.\n";
  148.     exit 1;
  149. }
  150.  
  151. if( @ARGV == 2 && $ARGV[0] =~ /^-[dbltirp]/ )
  152. {
  153.     warn "This option requires a list_alias and address.\n";
  154.     exit 1;
  155. }
  156.  
  157. $list = $ARGV[1];
  158. $list =~ tr/[a-z]/[A-Z]/;
  159.  
  160. $dir = "$listproc/lists/$list";
  161.  
  162. if( $ARGV[0] =~ /^-a/ )
  163. {
  164.     if( @ARGV == 2 )
  165.     {
  166.         print "\n    Enter the person's full name: ";
  167.         $name = <STDIN>;
  168.  
  169.         print   "        And their e-mail address: ";
  170.         $address = <STDIN>;
  171.         $address =~ tr/[a-z]/[A-Z]/;
  172.         }
  173.         else
  174.         {
  175.             $address = $ARGV[2];
  176.  
  177.             shift(@ARGV);
  178.             shift(@ARGV);
  179.             shift(@ARGV);
  180.  
  181.             if( @ARGV )
  182.             {
  183.                 $name = join(" ", @ARGV);
  184.             }
  185.         }
  186.     $address =~ tr/[a-z]/[A-Z/;
  187.     $list =~ tr/[A-Z]/[a-z]/;
  188.  
  189.     open(SUBS, "$dir/.subscribers")
  190.         || die "Can't open $dir/.subscribers: $!\n";
  191.  
  192.     while( <SUBS> )
  193.     {
  194.         if( /$address/o )
  195.         {
  196.             warn "$address is already on the $list list.\n";
  197.             close(SUBS);
  198.             exit 1;
  199.         }
  200.     }
  201.  
  202.     open(SUBS, ">> $dir/.subscribers")
  203.         || die "Can't open $dir/.subscribers: $!\n";
  204.  
  205.     print SUBS "$address ACK pass NO $name\n";
  206.     close(SUBS);
  207.         print "\n";
  208.  
  209.     &MailFile("$dir/.welcome", $address,
  210.         "Welcome to the $list mailing list!");
  211.  
  212.     exit 0;
  213. }
  214. elsif( $ARGV[0] =~ /^-([tidb])/ )
  215. {
  216.     $option = $1;
  217.  
  218.     open(TMP, "> /tmp/tt.$$");
  219.     select TMP;
  220.  
  221.     $list =~ tr/[A-Z]/[a-z]/;
  222.  
  223.     open(SUBS, "$dir/.subscribers")
  224.         || die "Can't open $dir/.subscribers: $!\n";
  225.  
  226.     while( <SUBS> )
  227.     {
  228.         if( /${ARGV[2]}/io )
  229.         {
  230.             $found = 1;
  231.         }
  232.     }
  233.  
  234.     if( !$found )
  235.     {
  236.         warn "$ARGV[2] not found on the $list list.\n";
  237.         unlink("/tmp/tt.$$");
  238.         close(SUBS);
  239.         exit 1;
  240.     }
  241.  
  242.     seek(SUBS, 0, 0);        # rewind
  243.  
  244.     while( <SUBS> )
  245.     {
  246.         if( /${ARGV[2]}/io )
  247.         {
  248.             next if( $option eq "d" );
  249.  
  250.             @line = split(" ", $_);
  251.             $line[1] = ($option eq "t") ? "POSTPONE" :
  252.                     (($option eq "b") ? "DIGEST" : "ACK");
  253.             $_ = join(" ", @line);
  254.  
  255.             print $_, "\n";
  256.         }
  257.         else
  258.         {
  259.             print;
  260.         }
  261.     }
  262.  
  263.     close(SUBS);
  264.     close(TMP);
  265.  
  266.     exec("mv /tmp/tt.$$ $dir/.subscribers")
  267.         || die "Can't execute 'mv': $!\n";
  268.  
  269.     &MailFile("$dir/.removed", $address,
  270.         "You have been removed from the $list mailing list");
  271. }
  272. elsif( $ARGV[0] =~ /^-l/ )
  273. {
  274.     open(SUBS, "$dir/.subscribers")
  275.         || die "Can't open $dir/.subscribers: $!\n";
  276.  
  277.     while( <SUBS> )
  278.     {
  279.         if( /POSTPONE/io )
  280.         {
  281.             @line = split(" ", $_);
  282.             print $line[0], "\n";
  283.         }
  284.     }
  285.     close(SUBS);
  286. }
  287. elsif( $ARGV[0] =~ /^-r/ )
  288. {
  289.     open(IGN, ">> $dir/.ignored")
  290.         || die "Can't open $dir/.ignored: $!\n";
  291.  
  292.     print IGN "$ARGV[2]\n";
  293.     close(IGN);
  294. }
  295. elsif( $ARGV[0] =~ /^-p/ )
  296. {
  297.     &MailFile("$dir/.moreinfo", $ARGV[2],
  298.         "Re: Your subscription request; more info is needed..");
  299. }
  300. elsif( $ARGV[0] =~ /^-f/ )
  301. {
  302.     $dir = "$listproc/lists";
  303.  
  304.     open(DIRS, "find $dir -type d -print |")
  305.         || die "Can't open 'find' pipe: $!\n";
  306.  
  307.     $junk = <DIRS>;
  308.     while( <DIRS> )
  309.     {
  310.         /([^\/\n]*)$/;
  311.  
  312.         $list = $1;
  313.         open(FILE, "$dir/$list/.subscribers")
  314.             || die "Can't open $dir/$list/.subscribers: $!\n";
  315.  
  316.         $title = 0;
  317.         $list =~ tr/[A-Z]/[a-z]/;
  318.  
  319.         while( <FILE> )
  320.         {
  321.             next if( ! /${ARGV[1]}/i );
  322.  
  323.             $title = 1 if( /${ARGV[1]}/i && $title == 0 );
  324.             if( $title == 1 )
  325.             {
  326.                 print "   --> $list\n";
  327.                 $title = 2;
  328.             }
  329.             print;
  330.         }
  331.         close(FILE);
  332.     }
  333.  
  334.     close(DIRS);
  335. }
  336.  
  337. #
  338. # Function:    MailFile
  339. #
  340. # Purpose:    to send a file via e-mail
  341. #
  342. # Vars:        $_[0]    - name of file to send
  343. #        $_[1]    - address of recipient
  344. #        $_[2]    - subject text
  345. #
  346. # Notes:    this function uses Elm's 'fastmail'.  You should
  347. #        rewrite this function to use whatever mailer is
  348. #        available on your system.  (Note that any requests
  349. #        sent to this function are not guaranteed to be
  350. #        printing files with e-mail headers in them).
  351. #
  352.  
  353. sub MailFile
  354. {
  355.     $command = "fastmail -s \"$_[2]\" $_[0] $_[1]";
  356.  
  357.     system($command);
  358.  
  359. } # MailFile(...
  360. ---EOF---
  361. ---[ file: prc.1 ]---
  362. .\" prc.1 by John Wiegley <johnw@bahainvs.org>.
  363. .\"
  364. .\" $Id: prc.1,v 1.1 93/10/23 18:42:34 jw Exp Locker: jw $
  365. .\"
  366. .TH PRC 1 "prc 1.0"
  367. .SH NAME
  368. prc \- ListProcessor 6.0 Local Control Program
  369. .SH SYNOPSIS
  370. .B prc
  371. [
  372. .B options
  373. ]
  374. [
  375. .B list_alias
  376. ]
  377. [
  378. .B address
  379. [
  380. .B full name
  381. ] ]
  382. .br
  383. .SH DESCRIPTION
  384. .I prc
  385. is a local control utility to facilitate user management under
  386. ListProcessor 6.0.  For those of us who find it faster to do these kinds
  387. of things under the shell, this little utility can save a lot of complex
  388. e-mail strings.
  389. .PP
  390. .I prc
  391. is written in perl, and should run on any system with perl 4.036 (and
  392. perhaps lower).
  393. .SH OPTIONS
  394. .TP 5
  395. .B \-a
  396. Add a user to a list.  If no address is given, one will be asked for.
  397. If a full name is given (shell quotes are not necessary), then it will
  398. also be used.
  399. .TP 5
  400. .B \-d
  401. Delete a person from a list.  ALL occurences matching "address" will
  402. be deleted.
  403. .TP 5
  404. .B \-t
  405. Temporarily mark a user as "down".  This feature uses the POSTPONE
  406. option to do its work.  In addition, it would probably be advantangous
  407. for ListProcessor to have a setting like TEMPDOWN, which would cause
  408. the tempdown'd user to receive an "Are you ok?" message every few
  409. weeks.
  410. .TP 5
  411. .B \-b
  412. Change a user's status to "DIGEST".
  413. .TP 5
  414. .B \-l
  415. List all addresses that are marked as "POSTPONE"d.  This feature
  416. can be used in a shell script (preferably called from cron) that
  417. will ping such addresses every once in a while, to see if they're
  418. back up yet or not.
  419. .TP 5
  420. .B \-i
  421. Reinstate a user who was been tempdown'd.  Basically, this just changes
  422. their status to ACK.  If you prefer NOACK as a default, you'll have to
  423. change the script...
  424. .TP 5
  425. .B \-r
  426. Add an address to the
  427. .I .ignored
  428. file.
  429. .TP 5
  430. .B \-p
  431. Send the contents of the
  432. .I .moreinfo
  433. file to the specified address.  This is not a standard ListProcessor 6.0
  434. file, and should be used only if you manually acknowledge subscription
  435. requests, and require "further information" before allowing them on the
  436. list.
  437. .TP 5
  438. .B \-f
  439. List all occurences of
  440. .I address
  441. in all
  442. .I .subscriber
  443. files.  This is useful for finding out if a person is on any of your lists.
  444. .TP 5
  445. .B \-h
  446. Print out the help message.
  447. .SH BUGS
  448. The code is kind of hard-wired to my own environment.  Also, it's not
  449. suited for being used as a setuid script.
  450. .PP
  451. The default password for all users is "pass".  Perhaps in the next
  452. version I'll support random passwords, and have an expansion variable
  453. available for use in the
  454. .I .welcome
  455. file.
  456. .SH AUTHOR
  457. John Wiegley
  458. <johnw@bahainvs.org>
  459. ---EOF---
  460.  
  461.